import java.util.Calendar;
import java.util.ArrayList;

/**
 * An Object of type DateList stores a list of Stats at the date the games were played.
 */
public class DateList 
{
	private ArrayList<DateNode> list;
	
	public DateList()
	{
		list= new ArrayList<DateNode>();
	}
	
	public DateList(SubitizePanel stats)
	{
		list= new ArrayList<DateNode>();
		addDateNode(stats);
	}
	
	
	/**
	 *  A adds a game to the list
	 * @param addition the SubitizePanel to add cannot be null
	 */
	public void addDateNode(SubitizePanel addition)
	{
		Calendar today= Calendar.getInstance();
		
		for(DateNode k : list)
		{
			if(k.getDate().get(Calendar.DAY_OF_YEAR)==today.get(Calendar.DAY_OF_YEAR)&&
			   k.getDate().get(Calendar.YEAR)==today.get(Calendar.YEAR))
			{
				k.getList().addGame(addition);
				return;
			}
		}
		list.add(new DateNode(addition));
	}
	
	public ArrayList<DateNode> getList()
	{
		return list;
	}
	
	public DateList getSubList(int minValue, int maxValue)
	{
		DateList temp= new DateList();
		for(DateNode k : list)
		{
			Stats nextStats= k.getList().getStats(minValue, maxValue);
			if(nextStats!=null) 
			{
				DateNode nextNode= new DateNode(k.date,
				StatsList.singleEntryList(nextStats, minValue, maxValue));
				temp.list.add(nextNode);
			}
		}
		return temp;
	}
	
	/**
	 * Generates a string representation of the DateList
	 */
	@Override 
	public String toString()
	{
		String temp= "";
		for(DateNode k : list)
		{
			temp+= k.toString();
		}
		return temp+"g";
	}
	
	/**
	 * Tests to see if the DateList has an entry for a specific date
	 * 
	 * @param date the Calendar to check for
	 * @return does the DateList contain an entry for this date
	 */
	public boolean containsDate(Calendar date)
	{
		for(DateNode k : list)
		{
			if(k.getDate().get(Calendar.DAY_OF_YEAR)==date.get(Calendar.DAY_OF_YEAR)&&
			   k.getDate().get(Calendar.YEAR)==date.get(Calendar.YEAR))
			{
				return true;
			}
		}
		return false;
	}
	
	public int indexOfDate(Calendar date)
	{
		for(int k=0; k<list.size(); k++)
		{
			if(list.get(k).getDate().get(Calendar.DAY_OF_YEAR)==
			   date.get(Calendar.DAY_OF_YEAR)&&
			   list.get(k).getDate().get(Calendar.YEAR)==date.get(Calendar.YEAR))
			{
				return k;
			}
		}
		return -1;
	}
	
	/**
	 * Reverses toString generates a DateList from a String representation
	 * @param source the String Representation
	 * @return the generated DateList
	 */
	public static DateList fromString(String source)
	{
		char[] chars= source.toCharArray();
		String next= "";
		long nextLong= 0;
		StatsList nextStatsList;
		Calendar nextCalendar;
		DateList temp= new DateList();
		boolean foundTime= false;
		
		for(int k=0; k<chars.length; k++)
		{
			if(chars[k]=='g') break;
			else if(chars[k]=='c'&&foundTime==false)
			{
				nextLong= Long.parseLong(next);
				next= "";
				foundTime= true;
				continue;
			}
			else if(chars[k]=='f')
			{
				nextStatsList= StatsList.fromString(next);
				nextCalendar= Calendar.getInstance();
				nextCalendar.setTimeInMillis(nextLong);
				temp.list.add(new DateNode(nextCalendar, nextStatsList));
				next= "";
				foundTime= false;
				continue;
			}
			else next+= chars[k];
		}
		return temp;
	}
	
	/**
	 * A Node storing a Date and Stats
	 */
	public static class DateNode
	{
		private Calendar date;
		private StatsList list;
		
		private DateNode(SubitizePanel panel)
		{
			date= Calendar.getInstance(); 
			list= new StatsList(panel);
		}
		
		private DateNode(Calendar date, StatsList list)
		{
			this.date= date;
			this.list= list; 
		}
		
		public Calendar getDate()
		{
			return date;
		}
		
		public StatsList getList()
		{
			return list;
		}
		
		/**
		 * Generates a String representation of the DateNode
		 */
		@Override 
		public String toString()
		{
			String temp= date.getTimeInMillis()+"c"+list.toString();
			return temp;
		}
	}
}
